抱着玩的心态,玩中看了几道题目,本来也想着看看XNUCA的题目的,无奈没有报上名。NCTF划划水….
基本操作 ~Reverse Version.~
elf64位,直接扔到IDA中,F5后,代码如下
1 | __int64 __fastcall main(__int64 a1, char **a2, char **a3) |
做了两处strcmp,其中地址s1的字符分别在函数sub_40666(0)和sub_4006BE(0, 0LL)中进行了赋值。进入sub_40666(0)中,通过递归对s1进行赋值。
1 | __int64 __fastcall sub_400666(signed int a1) |
通过递归依次对s1[0],s1[1],s1[2]….进行赋值,其值byte_601100[a1],逆向可以得到输入的字符byte_601100[a1]的值应该依次为s1[0],s1[1],s1[2],编写解题脚本如下:
1 | string_one = list("bcec8d7dcda25d91ed3e0b720cbb6cf202b09fedbc3e017774273ef5d5581794") |
FLAG:nctf{bc2e3b4c2eb03258c5102bf9de77f57dddad9edb70c6c20febc01773e5d81947}
Some Boxes
这个题目看了真的是好久,刚刚看到四步操作如下,以为是地图题目
1 | if ( v3 == 52 ) // 4 |
跟进函数后发现:
1 | result = (unsigned __int8)byte_6020A0[16 * dword5_6021B4_poi_col - 1 + dword80_6021B0_poi_line]; |
跟到byte_6020A0以为发现了新大陆,但是提取数据后长这样
1 | 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 16 |
这也不是地图啊,各种揪心中,然后函数中不是简单的++ – 各种操作,这都是什么!!!而且都是在和8做比较,地图里哪有那么多8。
1 | // 向左移动 |
查看程序对byte_6020A0的操作发现存在写操作,跟入,发现一个init函数中但是要修复栈帧后(要在报错的上一行ALT+K),后发现原来真正的地图要运行后才能得到。
1 | void *sub_400EB9() |
经过提取数据后得到地图,这才是真正的地图嘛。
1 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
然后通过最后的输出函数中的两个关键等式定位两个关键点,也就是在起始位置为37和120的两个点最后的位置处要等于20才能输出FLAG,而我们通过主函数可以确定最开始的起始点是88
1 | result = (unsigned __int8)byte_6020A0[16 * dword2_6021DC_one + dword5_6021D8_one];// res[37]的位置,起始值为37 |
一开始以为是该起始点带着其它的两个点,依次将他们送入最后的位置处,但是…error! error!再重新回到程序分析发现起始的标准点和其它的两个点根本不会相遇,而是推着他们走。再联想题目Some Box 。推箱子没问题了。按照题目要求,推一下箱子吧,手动玩游戏,得到最后的FLAG
1 | 输入: 444WW0W444W45555555450050W0000WWWWW5444WW00050W4W0000W0550544 |
Our 16bit wars
16位的汇编代码,反编译不存在的。一遍看INT 21h一遍解析代码,程序流程如下
1 | 显示提示 |
程序中主要的核心部分
1 | seg001:0059 sub_100F9 proc near ; CODE XREF: sub_100AC+1A↑p |
我们可以得指程序做的操作如下:
1 | for (int i=0;i<0x23;i++){ |
查看最后的比较函数
1 | seg001:0044 sub_100E4 proc near ; CODE XREF: sub_100AC+23↑p |
提取出做比较的字符串后,解题脚本如下:
1 | from z3 import * |
flag: NCTF{80x86_4ss3mble_1s_fund4m3nt4l}
后门后门后门
IDA经过F5反编译后,直接进入flag函数
1 | void __cdecl hereisyourflag() |
本机运行即可得到FLAG
感谢NCTF出题的师傅们,玩的很开心.